package bdd.sql.server.hibernate;

import ihm.applet.KrakenApplet;

import java.net.URL;
import java.util.Date;
import java.util.List;

import org.hibernate.HibernateException;
import org.hibernate.InstantiationException;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
import org.hibernate.criterion.Restrictions;
import org.hibernate.service.ServiceRegistry;
import org.hibernate.service.ServiceRegistryBuilder;

import bdd.sql.server.bean.Log;
import bdd.sql.server.bean.User;

/**
 * Wrapper pour démarrer Hibernate dans un bloc statique d'initialisation.
 * @author Scub-Foundation
 */
public class HibernateUtilNew {

	private static URL path_primary;
	private static SessionFactory sessionFactory_primary;
	private static ServiceRegistry serviceRegistry_primary;

	private static URL path_secondary;
	private static SessionFactory sessionFactory_secondary;
	private static ServiceRegistry serviceRegistry_secondary;

	public static boolean miroir = false;
	public static boolean connected = false;


	static {
		connected = false;
		miroir = true;
		while(!connected){
			try {
				Configuration configuration = null;

				//compatible pour nous deux, normalement, en utilisation locale
				if(!miroir) {
					path_primary = KrakenApplet.class.getResource("../../hibernate_standalone_SQLServer.cfg.xml");
					System.out.println(" xml from :"+path_primary);

					configuration = new Configuration();
					configuration.configure(path_primary);

					serviceRegistry_primary = new ServiceRegistryBuilder()
					.applySettings(configuration.getProperties())
					.buildServiceRegistry();        

					try {
						sessionFactory_primary = configuration.buildSessionFactory(serviceRegistry_primary);
						System.out.println("PrimaireOK " + sessionFactory_primary.getTypeHelper());
						connected = true;
						miroir = false;
					}
					catch(InstantiationException ex) {
						miroir = true;
						ex.printStackTrace();
					}
				}
				else {
					// fermer la premi�re connection
					HibernateUtilNew.closeSession_primary();

					path_secondary = KrakenApplet.class.getResource("../../hibernate_standalone_SQLServerMirror.cfg.xml");
					System.out.println(" xml from :"+path_secondary);

					configuration = new Configuration();
					configuration.configure(path_secondary);

					serviceRegistry_secondary = new ServiceRegistryBuilder()
					.applySettings(configuration.getProperties())
					.buildServiceRegistry();      
					
					System.out.println("Ici?");

					try {
						System.out.println("Ici?2");
						sessionFactory_secondary = configuration.buildSessionFactory(serviceRegistry_secondary);
						System.out.println("Ici?3");
						System.out.println("SecondaireOK "+sessionFactory_secondary.getTypeHelper());
						miroir = true;
						connected = true;
					}
					catch(InstantiationException ex) {
						miroir = false;
						ex.printStackTrace();
					}
				}
			} catch (Exception e) {
				e.printStackTrace();
			}
		}

	}

	/**
	 * Accesseur.
	 * @return la session existante
	 * @throws HibernateException
	 */
	public static Session getSession() throws HibernateException {
		if(!miroir)
			return sessionFactory_primary.openSession();
		else
			//sessionFactory_primary.close();
			return sessionFactory_secondary.openSession();
	}

	/**
	 * Ferme la session Hibernate.
	 * @throws HibernateException
	 */
	public static void closeSession_primary() throws HibernateException {
		try{
			path_primary = null;
			sessionFactory_primary.close();
			sessionFactory_primary = null;
			serviceRegistry_primary = null;
		} catch(Exception e){
			System.out.println("Tagada1");
		}
	}

	/**
	 * Ferme la session Hibernate.
	 * @throws HibernateException
	 */
	public static void closeSession_secondary() throws HibernateException {
		try{
			path_secondary = null;
			sessionFactory_secondary.close();
			sessionFactory_secondary = null;
			serviceRegistry_secondary = null;
		} catch(Exception e){
			System.out.println("Tagada2");
		}
	}

	/**
	 * Test si un champ existe déjà dans la base de données.
	 * @param session
	 * @param className
	 * @param field
	 * @param value
	 * @return boolean
	 * @throws HibernateException
	 */
	public static Boolean isFieldAlreadyExists(Session session, String className, String field, Object value) throws HibernateException  {
		try {
			@SuppressWarnings("unchecked")
			List<User> resultats = session.createCriteria(Class.forName(className)).add(Restrictions.eq(field, (Object)value)).list();
			if(resultats.size() > 0)	return true;
			else	return false;
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
			return true;
		}
	}

	public static void connectToBase() {
		Session session = null;
		Transaction tx = null;

		try{
			System.out.println("Connect to database, mirror="+miroir);


			//HibernateUtil.initSession();
			System.out.println("Session init, mirror="+miroir);
			session = HibernateUtil.getSession();
			System.out.println("get Session, mirror="+miroir);
			tx = session.beginTransaction();
			/*System.out.println("Transac session, mirror="+miroir);
			Log l = new Log("sortie garage", 2,new Date(), 5, 5, "Miroir Log!!");
			session.save(l);
			tx.commit();
			session.close();
			System.out.println("Session closed, mirror="+miroir);*/
		}
		catch (Exception e){
			miroir=true;
			System.out.println("exception, mirror="+miroir);
			//HibernateUtil.initSession();
			System.out.println("Session init, mirror="+miroir);
			session = HibernateUtil.getSession();
			System.out.println("get Session, mirror="+miroir);
			tx = session.beginTransaction();

		}
		System.out.println("Transac session, mirror="+miroir);

		//QUERY
		/*Log l = new Log("sortie garage", 2,new Date(), 5, 5, "Miroir Test!!");
		session.save(l);
		tx.commit();
		session.close();*/
		System.out.println("Session closed, mirror="+miroir);




	}


	public static void main(String[] args) {
		//miroir = false;
		//HibernateUtil.connectToBase();
		HibernateUtil.getSession();

	}

}
